﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using OtomatSearching.Engine;

namespace OtomatSearching
{
    public partial class frmMain : Form
    {
        #region Fields
        private DataTable TblKeywords;

        private readonly OtomatSearch otSearch;
        #endregion

        public frmMain()
        {
            InitializeComponent();
            otSearch = new OtomatSearch();
        }

        // Variables
        private int nextIndex = -1;

        private void chkPatternApproximate_CheckedChanged(object sender, EventArgs e)
        {
            try
            {
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnCheckPatternIsApproximate_Click(object sender, EventArgs e)
        {
            try
            {
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnClearRichtextBox_Click(object sender, EventArgs e)
        {
            try
            {
                this.richTextBox1.Text = this.richTextBox1.Text;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #region Event I/O Handle
        private void btnOpenFile_Click(object sender, EventArgs e)
        {
            try
            {
                OpenWordFile();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnOpenFileExcel_Click(object sender, EventArgs e)
        {
            try
            {
                OpenExcelFile();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void menuOpenWordFile_Click(object sender, EventArgs e)
        {
            try
            {
                OpenWordFile();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void menuOpenKeywordsList_Click(object sender, EventArgs e)
        {
            try
            {
                OpenExcelFile();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void dgridKeywordTable_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                var dgrid = sender as DataGridView;
                var keyword = dgrid[0, e.RowIndex].Value as String;
                if (String.IsNullOrWhiteSpace(keyword))
                {
                    return;
                }
                var pattern = keyword;
                // Reset back-color
                var sstart = this.richTextBox1.SelectionStart;
                this.richTextBox1.Text = this.richTextBox1.Text;
                this.richTextBox1.SelectionStart = sstart;
                // Parameters
                var osearch = new OtomatSearch();
                var listResult = osearch.Search(this.richTextBox1.Text, pattern, this.btnCheckPatternIsApproximate.Checked);
                this.richTextBox1.Tag = listResult;
                foreach (var item in listResult)
                {
                    if (item.Found == false)
                    {
                        continue;
                    }
                    // Tô màu
                    this.richTextBox1.Select(item.Postion, item.Length);
                    this.richTextBox1.SelectionBackColor = Color.Indigo;
                    this.richTextBox1.SelectionColor = Color.White;
                    this.richTextBox1.SelectionStart += item.Length;
                }
                if (listResult.Count > 0)
                {
                    var item = listResult[0];
                    this.richTextBox1.Select(item.Postion, item.Length);
                    this.richTextBox1.ScrollToCaret();
                    this.lbResult.Font = new Font(lbResult.Font, FontStyle.Bold);
                }
                else
                {
                    this.lbResult.Font = new Font(lbResult.Font, FontStyle.Regular);
                }
                this.lbResult.Text = string.Format("Found {0} result(s)", listResult.Count);
            }
            catch (Exception ex)
            {
                this.richTextBox1.SelectionStart = 0;
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        private void btnExportExcel_Click(object sender, EventArgs e)
        {
            try
            {
                if (TblKeywords == null || TblKeywords.Rows.Count == 0)
                {
                    MessageBox.Show("Bạn chưa chọn file keyword.", "Thông báo", MessageBoxButtons.OK);
                    return;
                }

                FileHelper.Export2Csv(TblKeywords);
            }
            catch (Exception ex)
            {
                this.richTextBox1.SelectionStart = 0;
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        #endregion

        #region Event function
        private void NextResult()
        {
            var listResult = this.richTextBox1.Tag as List<Oresult>;
            if (listResult == null || listResult.Count == 0)
            {
                return;
            }

            this.nextIndex = ++nextIndex % listResult.Count;
            var next = listResult[nextIndex];
            this.richTextBox1.Select(next.Postion, next.Length);
            this.richTextBox1.Focus();
        }

        private void PreviousResult()
        {
            var listResult = this.richTextBox1.Tag as List<Oresult>;
            if (listResult == null || listResult.Count == 0)
            {
                return;
            }

            this.nextIndex = (--nextIndex + listResult.Count) % listResult.Count;
            var next = listResult[nextIndex];
            this.richTextBox1.Select(next.Postion, next.Length);
            this.richTextBox1.Focus();
        }

        private void btnNextResult_Click(object sender, EventArgs e)
        {
            try
            {
                this.NextResult();
            }
            catch (Exception ex)
            {
                this.lbResult.Text = string.Format("Found 0 result(s)");
            }
        }

        private void btnPreviousResult_Click(object sender, EventArgs e)
        {
            try
            {
                this.PreviousResult();
            }
            catch (Exception ex)
            {
                this.richTextBox1.SelectionStart = 0;
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region Private Method
        private void OpenWordFile()
        {
            var fopen = new OpenFileDialog();
            fopen.Filter = "Supported Files (*.docx;*.doc)|*.docx;*.doc|docx File|*.docx|doc File|*.doc|All Files|*.*";
            if (DialogResult.OK == fopen.ShowDialog())
            {
                var text = FileHelper.ReadWordDocument(fopen.FileName);
                this.richTextBox1.Text = text;
                Count();
            }
        }

        private void OpenExcelFile()
        {
            var fopen = new OpenFileDialog();
            fopen.Filter = "Supported Files (*.xlsx;*.xls)|*.xls;*.xlsx|xlsx File (*.xlsx)|*.xlsx|xls File (*.xls)|*.xls|All Files|*.*";
            if (DialogResult.OK == fopen.ShowDialog())
            {
                var dt = FileHelper.ReadExcelFile(fopen.FileName);
                TblKeywords = ConvertTable(dt);
                dgridKeywordTable.DataSource = TblKeywords;
                Count();
            }
        }

        private DataTable ConvertTable(DataTable ip_dt, bool hasHeader = false)
        {
            DataTable result = new DataTable();
            result.Columns.Add("Keyword", typeof(string));
            result.Columns.Add("WordNumber", typeof(int));

            if (!hasHeader)
            {
                var dr = ip_dt.Rows[0];
                foreach (var cell in dr.ItemArray)
                {
                    result.Rows.Add(cell.ToString(), 0);
                }
            }

            for (int i = 1; i < ip_dt.Rows.Count; i++)
            {
                var dr = ip_dt.Rows[i];
                foreach (var cell in dr.ItemArray)
                {
                    if (string.IsNullOrEmpty(cell.ToString()))
                        continue;
                    result.Rows.Add(cell.ToString(), 0);
                }
            }

            return result;
        }

        private void Count()
        {
            if (this.richTextBox1.Text == "" || TblKeywords == null || TblKeywords.Rows.Count == 0)
                return;
            var text = this.richTextBox1.Text;

            foreach (DataRow dr in TblKeywords.Rows)
            {
                var pattern = dr[0].ToString();
                dr[1] = otSearch.Search(text, pattern, false).Count;
            }

            lblTotalWord.Text = string.Format("Total words: {0}", otSearch.GetWordNumber(text));
        }
        #endregion

        private void btnExportFolder_Click(object sender, EventArgs e)
        {
            if (TblKeywords == null || TblKeywords.Rows.Count == 0)
            {
                MessageBox.Show("Bạn chưa chọn file keyword.", "Thông báo", MessageBoxButtons.OK);
                return;
            }

            frmChooseFolder frmFolder = new frmChooseFolder();
            frmFolder.TblKeywords = TblKeywords;
            frmFolder.DataBind();
            frmFolder.ShowDialog(this);
        }

        private void richTextBox1_SelectionChanged(object sender, EventArgs e)
        {
            try
            {
                var text = richTextBox1.SelectedText;
                if (!string.IsNullOrEmpty(text))
                {
                    lblSelectedWord.Text = string.Format("Selected words: {0}", otSearch.GetWordNumber(text));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void richTextBox1_Click(object sender, EventArgs e)
        {
            try
            {
                var text = richTextBox1.SelectedText;
                if (string.IsNullOrEmpty(text))
                {
                    lblSelectedWord.Text = string.Format("Selected words: {0}", otSearch.GetWordNumber(text));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
